#pragma once
#include <tuple>
using std::tuple;
using std::forward;
using std::get;

// IndexTuple 是一个可变参数模板结构体，用于存储整数序列
template<int...>
struct IndexTuple{};

// 前向声明 make_indexes_impl
template<int I, typename IndexTuple, typename... Types>
struct make_indexes_impl;

// make_indexes_impl 的主要实现
// 通过递归方式，逐步构建索引序列，从I开始，每次加1
template<int I, int... Indexes, typename T, typename... Types>
struct make_indexes_impl<I, IndexTuple<Indexes...>, T, Types...>
{
	// 递归调用，将当前索引I添加到序列中
	using type = typename make_indexes_impl<I + 1, IndexTuple<Indexes..., I>, Types...>::type;
};

// make_indexes_impl 的特化版本，递归终止条件
template<int I, int... Indexes>
struct make_indexes_impl<I, IndexTuple<Indexes...>>
{
	using type = IndexTuple<Indexes...>;
};

// 用户接口，用于生成从0开始的连续索引序列
template<typename ... Types>
struct make_indexes : make_indexes_impl<0, IndexTuple<>, Types...>
{};

/*********************************************/
template<int I, typename IndexTuple, typename... Types>
struct make_indexes_reverse_impl;

// 反向索引的主要实现，从最大值开始递减
template<int I, int... Indexes, typename T, typename... Types>
struct make_indexes_reverse_impl<I, IndexTuple<Indexes...>, T, Types...>
{
	using type = typename make_indexes_reverse_impl<I-1, IndexTuple<Indexes..., I - 1>, Types...>::type;
};

// 反向索引的终止条件
template<int I, int... Indexes>
struct make_indexes_reverse_impl<I, IndexTuple<Indexes...>>
{
	using type = IndexTuple<Indexes...>;
};

// 反向索引的用户接口
template<typename ... Types>
struct make_reverse_indexes : make_indexes_reverse_impl<sizeof...(Types), IndexTuple<>, Types...>
{};
/*********************************************/

// 第二种生成索引序列的方法
// 从N开始，通过继承方式逐步构建序列
template<int N, int... Indexes>
struct make_indexes2 : make_indexes2<N - 1, N - 1, Indexes...> {};

// make_indexes2 的终止条件
template<int... Indexes>
struct make_indexes2<0, Indexes...>
{
	typedef IndexTuple<Indexes...> type;
};

/***********************************************/

// 第三种生成索引序列的方法
// 从起始值递增到结束值
template< int end, int cur, int... Indexes >
struct make_indexes3 : make_indexes3< end, cur + 1, Indexes..., cur >{};

// make_indexes3 的终止条件
template< int end, int... Indexes >
struct make_indexes3< end, end, Indexes... >
{
	typedef IndexTuple<Indexes...> type;
};

/***********************************************/
